import { type Skill, SkillType, TargetType } from './Skill';

export class Character {
    name: string;
    health: number;
    attack: number;
    defense: number;
    strategy: number; // 谋略值
    strategyDefense: number; // 谋略防御
    isDead: boolean = false;
    skills: Skill[] = [];
    passiveSkillsExecuted: boolean = false; // 记录被动战法是否已执行

    constructor(
        name: string,
        health: number,
        attack: number,
        defense: number,
        strategy: number, // 谋略值
        strategyDefense: number, // 谋略防御
        skills: Skill[] = []
    ) {
        this.name = name;
        this.health = health;
        this.attack = attack;
        this.defense = defense;
        this.strategy = strategy;
        this.strategyDefense = strategyDefense;
        this.skills = skills;
    }

    takeDamage(damage: number, log?: (message: string) => void): void {
        if (this.isDead) return;

        this.health -= damage;
        if (this.health < 0) {
            this.health = 0;
        }

        if (this.health === 0 && !this.isDead) {
            this.isDead = true;
            log?.(`${this.name} 阵亡了！`);
        }
    }

    takeStrategyDamage(damage: number, log?: (message: string) => void): void {
        if (this.isDead) return;

        const finalDamage = Math.max(0, damage - this.strategyDefense); // 计算谋略伤害
        this.takeDamage(finalDamage, log);
    }

    isAlive(): boolean {
        return this.health > 0;
    }

    calculateDamage(attacker: Character, target: Character, damageRate: number): number {
        // 伤害计算公式：攻击伤害 = 攻击 * 伤害率 * (1 - 防御减伤) + F(血量)
        const defenseReduction = target.defense / (target.defense + 100); // 防御减伤公式
        const baseDamage = attacker.attack * damageRate * (1 - defenseReduction);
        const healthBonus = Math.sqrt(target.health) * 0.1; // F(血量) = sqrt(血量) * 0.1
        return Math.max(0, Math.floor(baseDamage + healthBonus)); // 确保伤害不为负数
    }

    attackTarget(target: Character, log?: (message: string) => void): void {
        if (this.isDead || target.isDead) return;

        // 触发主动技能
        this.skills
            .filter(skill => skill.type === SkillType.Active && skill.targetType === TargetType.Enemy)
            .forEach(skill => skill.execute(this, target, log));

        const damage = this.calculateDamage(this, target, 1); // 默认伤害率为 1
        const remainingHealth = Math.max(0, target.health - damage); // 计算剩余血量
        log?.(`${this.name} 攻击了 ${target.name}，造成了 ${damage} 点伤害！【剩余血量：${remainingHealth}】`);
        target.takeDamage(damage);
    }

    castStrategySkill(target: Character, log?: (message: string) => void): void {
        if (this.isDead || target.isDead) return;

        // 触发谋略技能
        this.skills
            .filter(skill => skill.type === SkillType.Strategy && skill.targetType === TargetType.Enemy)
            .forEach(skill => {
                const damage = this.calculateDamage(this, target, 1.5); // 默认伤害率为 1.5
                const remainingHealth = Math.max(0, target.health - damage); // 计算剩余血量
                log?.(`${this.name} 触发谋略技能【${skill.name}】，对 ${target.name} 造成 ${damage} 点谋略伤害！【剩余血量：${remainingHealth}】`);
                target.takeStrategyDamage(damage);
            });
    }

    executeCommandSkills(log?: (message: string) => void): void {
        // 触发指挥技能
        this.skills
            .filter(skill => skill.type === SkillType.Command && skill.targetType === TargetType.Ally)
            .forEach(skill => skill.execute(this, undefined, log));
    }

    executePassiveSkills(log?: (message: string) => void): void {
        // 被动战法只执行一次
        if (!this.passiveSkillsExecuted) {
            this.skills
                .filter(skill => skill.type === SkillType.Passive && skill.targetType === TargetType.Ally)
                .forEach(skill => skill.execute(this, undefined, log));
            this.passiveSkillsExecuted = true; // 标记为已执行
        }
    }

    castBeneficialSkill(target: Character, log?: (message: string) => void): void {
        if (this.isDead || target.isDead) return;

        // 触发益处的技能
        this.skills
            .filter(skill => skill.targetType === TargetType.Ally)
            .forEach(skill => skill.execute(this, target, log));
    }
}